1. Technical Field
This disclosure generally relates to debuggers, and more specifically relates to holding threads in debuggers.
2. Background Art
Computer systems have evolved into extremely sophisticated devices, and may be found in many different settings. Computer systems typically include a combination of hardware, such as semiconductors and circuit boards, and software, also known as computer programs. As advances in semiconductor processing and computer architecture push the performance of the computer hardware higher, more sophisticated computer software has evolved to take advantage of the higher performance of the hardware, resulting in computer systems today that are much more powerful than just a few years ago.
As the sophistication and complexity of computer software increase, the more difficult the software is to debug. Debugging is the process of finding problems, or “bugs”, during the development of a computer program. Most modern programming environments include a debugger that provides tools for testing and debugging a computer program. Debuggers allow setting breakpoints in a computer program. When a breakpoint is encountered, execution of the computer program is halted to allow inspecting the state of the computer program, or to allow executing instructions one at a time in a single step mode.
When debugging a computer program that includes multiple threads, a debugger typically halts and holds all threads when the debugger stops execution of the computer program. This can lead to conditions that can create a deadlock under certain circumstances. A program can make calls to the operating system to perform services on behalf of the program. A debugger also makes such calls to the operating system. When the debugger holds all threads for a program, if one of the threads is executing system code that is needed by the debugger, the result is a deadlock.
Similar deadlock problems can arise when building an environment such as UNIX on top of an existing operating system. The underlying operating system may have a concurrency control mechanism called a mutex. Because the UNIX System Services kernel is implemented above the underlying operating system, it cannot interrupt a thread waiting on one of these concurrency mechanisms. In some systems such as the zOS operating system by IBM, this low level concurrency mechanism is called a latch.
When a stop occurs, let's assume a thread is held within one of these critical sections of the underlying operating system that are guarded with a latch, and one of the threads waiting on the latch turns out to be the current or focus thread of the debugger. This means that when the debugger sends requests to the USS kernel, that kernel will have to run some amount of code to satisfy the request within the current or focus thread. But if this thread is waiting on a latch then the kernel can not interrupt it to run the code needed to satisfy the request. The result is that the kernel code is queued up on the latch which will never be released because the thread that is holding it is held by the debugger and the debugger hangs due to this deadlock condition.
Without a way to resolve these deadlock conditions described above, known debuggers will periodically lock up when the debugger waits for a thread executing system code that has already been halted by the debugger.